﻿using System.Collections.Generic;
using TrueSync;
using UnityEngine;
using UnityEngine.UIElements;

namespace HEFramework
{
    public static class SkillEffectTargetComponentSystem
    {
        [EntitySystem]
        public class SkillEffectTargetComponentAwakeSystem : AwakeSystem<SkillEffectTargetComponent>
        {
            protected override void Awake(SkillEffectTargetComponent _self)
            {
            }
        }

        public static int Ready(this SkillEffectTargetComponent _self, int _id, Entity _receiver, TSVector _pos, bool _isActive)
        {
            var dc = _self.GetSceneChild<DataTableComponent>();
            if (dc == null)
            {
                return (int)eSkillErrorCode.System;
            }

            var sec = _self.GetParent<SkillEffectComponent>();
            if (sec == null)
            {
                return (int)eSkillErrorCode.System;
            }

            var ac = _self.GetMainEntity().GetChild<AttributeComponent>();
            if (ac == null)
            {
                return (int)eSkillErrorCode.System;
            }

            //获取技能效果组
            using ListObject<int> ids = sec.GetEffectIDs(_id, _isActive);
            if (ids.Count <= 0)
            {
                return (int)eSkillErrorCode.System;
            }

            var main = _self.GetMainEntity();


            //判断所有效果 有一个效果通过就执行
            bool isTarget = false;
            var table = dc.LoadDataTable<DRSkillEffect>();
            for (int i = 0; i < ids.Count; i++)
            {
                var sData = table.GetData(ids[i]);
                switch (sData.AreaType)
                {
                    case (int)eSkillEffectAreaType.Single:
                        if (_receiver == null)
                        {
                            return (int)eSkillErrorCode.WrongTarget;
                        }

                        if (_self.IsSkillEffectTarget(main, _receiver, sData.ID))
                        {
                            isTarget = true;
                        }

                        break;
                    case (int)eSkillEffectAreaType.Area:
                        //可以检测区域是否合法，目前任何区域都合法
                        isTarget = true;
                        break;
                }

                if (isTarget)
                {
                    break;
                }
            }

            //选择的对象不是正确目标
            if (!isTarget)
            {
                return (int)eSkillErrorCode.WrongTarget;
            }

            return (int)eSkillErrorCode.None;
        }

        /// <summary>
        /// 是否单体技能
        /// </summary>
        /// <param name="_self"></param>
        /// <param name="_id">技能ID</param>
        /// <param name="_isActive">是否主动效果</param>
        /// <returns></returns>
        public static bool IsSingle(this SkillEffectTargetComponent _self, int _id, bool _isActive)
        {
            var dc = _self.GetSceneChild<DataTableComponent>();
            if (dc == null)
            {
                return false;
            }

            var sec = _self.GetParent<SkillEffectComponent>();
            if (sec == null)
            {
                return false;
            }

            //检测该技能所有效果选择对象
            using ListObject<int> ids = sec.GetEffectIDs(_id, _isActive);
            if (ids.Count <= 0)
            {
                return false;
            }

            var table = dc.LoadDataTable<DRSkillEffect>();
            for (int i = 0; i < ids.Count; i++)
            {
                //如果有区域效果，则不为单体
                var eData = table.GetData(ids[i]);
                if (eData.AreaType == (int)eSkillEffectAreaType.Area)
                {
                    return false;
                }
            }

            return true;
        }


        /// <summary>
        /// 获取技能目标对象【引用后需释放列表】
        /// </summary>
        /// <param name="_self"></param>
        /// <param name="_id"></param>
        /// <param name="_receiver"></param>
        /// <param name="_pos"></param>
        /// <returns></returns>
        public static ListObject<Entity> GetTargets(this SkillEffectTargetComponent _self, int _id, Entity _receiver, TSVector _pos)
        {
            var entities = ListObject<Entity>.Create();
            var dc = _self.GetSceneChild<DataTableComponent>();
            if (dc == null)
            {
                return entities;
            }

            var table = dc.LoadDataTable<DRSkillEffect>();
            if (table == null)
            {
                return entities;
            }

            var serc = _self.GetParentChild<SkillEffectRangeComponent>();
            if (serc == null)
            {
                return entities;
            }

            var data = table.GetData(_id);
            var main = _self.GetMainEntity();
            switch (data.AreaType)
            {
                case (int)eSkillEffectAreaType.Single:
                {
                    if (_receiver != null)
                    {
                        if (_self.IsSkillEffectTarget(main, _receiver, data.ID))
                        {
                            entities.Add(_receiver);
                        }
                    }
                }
                    break;
                case (int)eSkillEffectAreaType.Area:
                {
                    using var targets = _self.GetScene().GetChildList<Entity>();
                    TransformComponent tcA = main.GetChild<TransformComponent>();
                    TransformComponent tcB;
                    if (tcA != null)
                    {
                        for (int i = 0; i < targets.Count; i++)
                        {
                            var target = targets[i];
                            if (!_self.IsSkillEffectTarget(main, target, data.ID))
                            {
                                continue;
                            }

                            tcB = target.GetChild<TransformComponent>();
                            if (tcB != null)
                            {
                                TSVector dir = tcB.P - tcA.P;
                                if (serc.InEffectRange(_id, _pos, tcB.P, dir))
                                {
                                    entities.Add(target);
                                }
                            }
                        }
                    }
                }
                    break;
            }

            return entities;
        }

        /// <summary>
        /// A是否可以对B释放某技能效果
        /// </summary>
        /// <param name="_self"></param>
        /// <param name="_a"></param>
        /// <param name="_b"></param>
        /// <param name="_id"></param>
        /// <returns></returns>
        private static bool IsSkillEffectTarget(this SkillEffectTargetComponent _self, Entity _a, Entity _b, int _id)
        {
            if (_a == null)
            {
                return false;
            }

            if (_b == null)
            {
                return false;
            }

            var dc = _self.GetSceneChild<DataTableComponent>();
            if (dc == null)
            {
                return false;
            }

            var acA = _a.GetChild<AttributeComponent>();
            var acB = _b.GetChild<AttributeComponent>();
            if (acA == null || acB == null)
            {
                return false;
            }

            var data = dc.LoadDataTable<DRSkillEffect>()?.GetData(_id);
            if (data == null)
            {
                return false;
            }

            switch (data.TargetType)
            {
                //自身
                case (int)eSkillEffectTargetType.Self:
                    if (!acA.IsSelf(acB))
                    {
                        return false;
                    }

                    break;
                //我方
                case (int)eSkillEffectTargetType.Team:
                    if (!acA.IsTeam(acB))
                    {
                        return false;
                    }

                    break;
                //友方
                case (int)eSkillEffectTargetType.Friend:
                    if (!acA.IsFriend(acB))
                    {
                        return false;
                    }

                    break;
                //敌方
                case (int)eSkillEffectTargetType.Enemy:
                    if (!acA.IsEnemy(acB))
                    {
                        return false;
                    }

                    break;
                //非自身我方
                case (int)eSkillEffectTargetType.TeamNoSelf:
                    if (acA.IsSelf(acB) || !acA.IsTeam(acB))
                    {
                        return false;
                    }

                    break;
                //全部
                case (int) eSkillEffectTargetType.All:
                    break;
            }


            //属性目标确认
            for (int i = 0; i < data.TargetATypes.Length; i++)
            {
                if (data.TargetATypes[i] == acB.Attribute.Type)
                {
                    return true;
                }
            }


            return false;
        }

        private static Entity GetMainEntity(this SkillEffectTargetComponent _self)
        {
            return _self.Parent.Parent.Parent;
        }
    }
}